package com.tsinghuabigdata.edu.ddmath.module.neteaseim.education.doodle;

import android.text.TextUtils;

import com.tsinghuabigdata.edu.ddmath.module.neteaseim.education.doodle.action.DrawCacheManager;

import java.io.Serializable;

/**
 * Created by huangjun on 2015/6/24.
 */
public class Transaction implements Serializable {
    private static final String TAG = Transaction.class.getSimpleName();

    public interface ActionStep {
        byte START = 11;
        byte MOVE = 12;
        byte END = 13;

        byte REVOKE = 14;
        byte CLEAR = 15;
        byte CLEAR_ACK = 16;
        byte SHOW = 21;
        byte IMGMOVE = 22;
        byte SYNCR = 1;
        byte SYNCD = 2;
        byte ASK = 3;
        byte ACK = 4;
        byte SWITCH_CHANNEL = 5;


//        byte SERIAL = 5;
//        byte SYNC_REQUEST = 8;
//        byte SYNC = 9;
//        byte SYNC_PREPARE = 10;
//        byte SYNC_PREPARE_ACK = 11;
//        byte LASER_PEN = 12;
//        byte LASER_PEN_END = 13;
//        byte Flip = 14;
    }

    public interface Channel {
        byte WHITE_DOODLE = 1;  //白板
        byte QUESTION = 2;   //题集
        byte COURSE = 3;  //课件
    }

    private byte step = ActionStep.START;
    private float x = 0.0f;
    private float y = 0.0f;
    private int paintSize = 1;
    private int rgb;
    private String uid;
    private int end;


    private int channel = Channel.WHITE_DOODLE; //白板，题集，课件三类
    private int currentPageNum;//当前通道的页码
    private String imgUrl;
    private String syncData;

    public Transaction() {
    }

    /**
     * 笔记类数据
     *
     * @param step
     * @param x
     * @param y
     * @param rgb
     */
    public Transaction(byte step, float x, float y, int rgb) {
        //默认的是白板并且是第一面
        this.step = step;
        this.x = x;
        this.y = y;
        this.rgb = rgb;
    }

    /**
     * 图片类数据
     *
     * @param step
21-2-1:question/stu;
     *             21-3-4:course/teacher;
     *             22-2-2: 0.12,0.12;
     */
    public Transaction(byte step, int channel, int page, String url) {
        this.step = step;
        this.channel = channel;
        this.currentPageNum = page;
        this.imgUrl = url;
    }

    /**
     * 指令类
     *
     * @param step
     */
    public Transaction(byte step) {
        this.step = step;
    }

    public Transaction(byte step, int channel, int pagenum) {
        this.step = step;
        this.channel = channel;
        this.currentPageNum = pagenum;
    }

    public Transaction(byte step, int channel) {
        this.step = step;
        this.channel = channel;
    }

    public static String pack(Transaction t) {
        /**
         * type-channel-page: 坐标x,坐标y,颜色,粗细;
         * type-channel-page:URL;
         * type-account:data（data为指令的集合，分别用”#”、”$”、”%”替换指令中的”-“、”:”、”;”）
         * type;
         * type-channel;
         */
        if (t.getStep() == ActionStep.CLEAR || t.getStep() == ActionStep.REVOKE
                || t.getStep() == ActionStep.CLEAR_ACK) {
            return String.format("%d-%d-%d;", t.getStep(), t.getChannel(), t.getCurrentPageNum());
        } else if (t.getStep() == ActionStep.SHOW) {
            return String.format("%d-%d-%d:%s;",
                    t.getStep(), t.getChannel(), t.getCurrentPageNum(), t.getImgUrl());
        } else if (t.getStep() == ActionStep.IMGMOVE) {
            return String.format("%d-%d-%d:%d,%d;",
                    t.getStep(), t.getChannel(), t.getCurrentPageNum(), t.getX(), t.getY());
        } else if (t.getStep() == ActionStep.SYNCR || t.getStep() == ActionStep.ASK || t.getStep() == ActionStep.ACK) {
            return String.format("%d;", t.getStep());
        } else if (t.getStep() == ActionStep.SYNCD) {
            return String.format("%d-%s:%s;",
                    t.getStep(), t.getUid(), t.getSyncData());
        } else if (t.getStep() == ActionStep.SWITCH_CHANNEL) {
            return String.format("%d-%d;", t.getStep(), t.getChannel());
        }
        return String.format("%d-%d-%d:%f,%f,%d,%d;", t.getStep(), t.getChannel(), t.getCurrentPageNum(),
                t.getX(), t.getY(), t.getRgb(), t.getPaintSize());
    }

    public static String packIndex(int index) {
        return String.format("5:%d,0;", index);
    }



    /**
     * 解析单个指令
     * @param data  单个指令数据
     * @return   指令对象
     */
    public static Transaction unpack(String data) {

        //数据为空
        if(TextUtils.isEmpty(data))
            return null;

        //去掉“;”
        data = data.replace(";","");

        //分成指令和数据两部分
        String cmd, cmddata = null;
        int index = data.indexOf(":");
        if( index < 0 ){
            cmd = data;
            cmddata = null;
        }else{
            cmd = data.substring( 0, index );
            if( index+1 < data.length() )
                cmddata = data.substring( index+1 );
        }

        //指令是空
        if(TextUtils.isEmpty(cmd))
            return null;

        byte step;
        Transaction transaction = null;
        try {

            String cmdArray[] = cmd.split("-");
            step = Byte.parseByte(cmdArray[0]);

            if( cmdArray.length == 1 ){     //
                transaction = new Transaction( step );
            }else if( cmdArray.length == 2 ){

                switch( step ){
                    case ActionStep.SYNCD:{ //data为指令的集合，分别用”#”、”$”、”%”替换指令中的”-“、”:”、”;” 要复原
                        String account = cmdArray[1];

                        if( TextUtils.isEmpty(cmddata) )
                            break;

                        cmddata = cmddata.replace("#","-");
                        cmddata = cmddata.replace("$",":");
                        cmddata = cmddata.replace("%",";");

                        transaction = new Transaction();
                        transaction.make( step, account, cmddata );
                        break;
                    }
                    case ActionStep.SWITCH_CHANNEL:{
                        int channel = Integer.parseInt( cmdArray[1] );
                        transaction = new Transaction( step, channel );
                        break;
                    }
                }

            } else if( cmdArray.length == 3 ){

                int channel = Integer.parseInt( cmdArray[1] );
                int page    = Integer.parseInt( cmdArray[2] );

                switch( step ){
                    case ActionStep.START:
                    case ActionStep.MOVE:
                    case ActionStep.END:{
                        //坐标x,坐标y,颜色,粗细
                        if( TextUtils.isEmpty(cmddata) )
                            break;
                        String array[] = cmddata.split(",");

                        if( array.length < 3 || TextUtils.isEmpty(array[0]) || TextUtils.isEmpty(array[1]) || TextUtils.isEmpty(array[2]) )
                            break;
                        float x = Float.parseFloat( array[0] );
                        float y = Float.parseFloat( array[1] );
                        int   c = Integer.parseInt( array[2] );
                        int   b = 0;
                        if( array.length >= 4 ){
                            if(  TextUtils.isEmpty(array[3] ) )
                                break;
                            b = Integer.parseInt( array[3] );
                        }

                        transaction = new Transaction();
                        transaction.make( step, channel, page, x, y, c, b );

                        break;
                    }
                    case ActionStep.CLEAR:
                    case ActionStep.CLEAR_ACK:
                    case ActionStep.REVOKE:{
                        transaction = new Transaction( step, channel, page );
                        break;
                    }
                    case ActionStep.SHOW:{

                        if( TextUtils.isEmpty(cmddata) )
                            break;

                        transaction = new Transaction();
                        transaction.makeImageShowTransaction( step, channel, page, cmddata );
                        break;
                    }

                    case ActionStep.IMGMOVE:{

                        if( TextUtils.isEmpty(cmddata) )
                            break;
                        String xy[] = cmddata.split(",");
                        if( xy.length!=2 || TextUtils.isEmpty(xy[0]) || TextUtils.isEmpty(xy[1]) )
                            break;
                        float x = Float.parseFloat( xy[0] );
                        float y = Float.parseFloat( xy[1] );
                        transaction = new Transaction();
                        transaction.makeImageMoveTransaction( step, channel, page, x, y );
                        break;
                    }
                }

            //}else {
                //非法指令
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return transaction;
    }

    /**
     * 生成画笔数据
     *
     * @param step
     * @param x
     * @param y
     * @param rgb
     * @param channel
     * @param currentPageNum
     */
    private void make(byte step, float x, float y, int rgb, int channel, int currentPageNum) {
        this.step = step;
        this.x = x;
        this.y = y;
        this.rgb = rgb;
        this.channel = channel;
        this.currentPageNum = currentPageNum;
    }

    private void make(byte step, int channel, int page, float x, float y, int color, int thick ) {
        this.step = step;
        this.x = x;
        this.y = y;
        this.rgb = color;
        this.channel = channel;
        this.paintSize = thick;
        this.currentPageNum = page;
    }

    private void make(byte step, float x, float y, int rgb) {
        this.step = step;
        this.x = x;
        this.y = y;
        this.rgb = rgb;
        this.channel = DrawCacheManager.getInstance().getCurrentChannel();
        this.currentPageNum = DrawCacheManager.getInstance().getCurrentPageNum();
    }

    private void make(byte step, String uid, int end) {
        this.uid = uid;
        this.step = step;
        this.end = end;
    }

    public Transaction make(byte step, String account, String syncData) {
        this.step = step;
        this.uid = account;
        this.syncData = syncData;
        return this;
    }

    private void makeImageShowTransaction(byte step, int channel, int pagenum, String url){
        this.step = step;
        this.channel = channel;
        this.currentPageNum = pagenum;
        this.imgUrl = url;
    }

    private void makeImageMoveTransaction(byte step, int channel, int pagenum, float x, float y ){
        this.step = step;
        this.channel = channel;
        this.currentPageNum = pagenum;
        this.x = x;
        this.y = y;
    }

    /**
     * 生成指令
     *
     * @param step
     */
    private void make(byte step) {
        this.step = step;
        this.channel = DrawCacheManager.getInstance().getCurrentChannel();
        this.currentPageNum = DrawCacheManager.getInstance().getCurrentPageNum();
    }

    private void make(byte step, int channel, int pagenum) {
        this.step = step;
        this.channel = channel;
        this.currentPageNum = pagenum;
    }

    public Transaction makeStartTransaction(float x, float y, int rgb) {
        make(ActionStep.START, x, y, rgb);
        return this;
    }

    public Transaction makeMoveTransaction(float x, float y, int rgb) {
        make(ActionStep.MOVE, x, y, rgb);
        return this;
    }

    public Transaction makeEndTransaction(float x, float y, int rgb) {
        make(ActionStep.END, x, y, rgb);
        return this;
    }

    public Transaction makeStartTransaction(float x, float y, int rgb, int channel, int pagenum) {
        make(ActionStep.START, x, y, rgb, channel, pagenum);
        return this;
    }

    public Transaction makeMoveTransaction(float x, float y, int rgb, int channel, int pagenum) {
        make(ActionStep.MOVE, x, y, rgb, channel, pagenum);
        return this;
    }

    public Transaction makeEndTransaction(float x, float y, int rgb, int channel, int pagenum) {
        make(ActionStep.END, x, y, rgb, channel, pagenum);
        return this;
    }

    public Transaction makeRevokeTransaction() {
        make(ActionStep.REVOKE);
        return this;
    }

    public Transaction makeClearSelfTransaction() {
        make(ActionStep.CLEAR);
        return this;
    }

    public Transaction makeClearAckTransaction() {
        make(ActionStep.CLEAR_ACK);
        return this;
    }

    public Transaction makeRevokeTransaction(int channel, int pagenum) {
        make(ActionStep.REVOKE, channel, pagenum);
        return this;
    }

    public Transaction makeClearSelfTransaction(int channel, int pagenum) {
        make(ActionStep.CLEAR, channel, pagenum);
        return this;
    }

    public Transaction makeClearAckTransaction(int channel, int pagenum) {
        make(ActionStep.CLEAR_ACK, channel, pagenum);
        return this;
    }

    public Transaction makeSyncRequestTransaction() {
        make(ActionStep.SYNCR);
        return this;
    }
//
//    public Transaction makeSyncTransaction(String uid, int end) {
//        make(ActionStep.SYNC, uid, end);
//        return this;
//    }
//
//    public Transaction makeSyncPrepareTransaction() {
//        make(ActionStep.SYNC_PREPARE);
//        return this;
//    }
//
//    public Transaction makeSyncPrepareAckTransaction() {
//        make(ActionStep.SYNC_PREPARE_ACK);
//        return this;
//    }
//
//    public Transaction makeFlipTranscation(String docId, int currentPageNum, int pageCount, int type) {
//        make(ActionStep.Flip, docId, currentPageNum, pageCount, type);
//        return this;
//    }

    public int getStep() {
        return step;
    }

    public float getX() {
        return x;
    }

    public float getY() {
        return y;
    }

    public int getRgb() {
        return rgb;
    }

    public int getPaintSize() {
        return paintSize;
    }

    public String getUid() {
        return uid;
    }

    public int getEnd() {
        return end;
    }

    public int getChannel() {
        return channel;
    }

    public String getImgUrl() {
        return imgUrl;
    }

    public void setSyncData(String syncData) {
        this.syncData = syncData;
    }

    public String getSyncData() {
        return syncData;
    }

    public int getCurrentPageNum() {
        return currentPageNum;
    }

    public void setCurrentPageNum(int currentPageNum) {
        this.currentPageNum = currentPageNum;
    }

    public boolean isPaint() {
        return !isRevoke() && !isClearSelf() && !isClearAck();
    }

    public boolean isRevoke() {
        return step == ActionStep.REVOKE;
    }

    public boolean isClearSelf() {
        return step == ActionStep.CLEAR;
    }

    public boolean isClearAck() {
        return step == ActionStep.CLEAR_ACK;
    }

//    public boolean isSyncRequest() {
//        return step == ActionStep.SYNC_REQUEST;
//    }
//
//    public boolean isSync() {
//        return step == ActionStep.SYNC;
//    }
//
//    public boolean isSyncPrepare() {
//        return step == ActionStep.SYNC_PREPARE;
//    }
//
//    public boolean isSyncPrepareAck() {
//        return step == ActionStep.SYNC_PREPARE_ACK;
//    }
//
//    public boolean isLaserPen() {
//        return step == ActionStep.LASER_PEN;
//    }
//
//    public boolean isLaserPenEnd() {
//        return step == ActionStep.LASER_PEN_END;
//    }
//
//    public boolean isFlip() {
//        return step == ActionStep.Flip;
//    }
}
